/**
 * @author chen han
 * a process lock transplant from linux process management,
 * which used to ensure every program only start with one instance,
 * when a program start to run, it lock a file, 
 * if lock success, the program can continue, and the program should to 
 * be a observer for the lock, so, when the lock can notify the program some 
 * message when the lock file change
 * or program should to exit
 */

package zheezes.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Observable;

public class ProcLock extends Observable {
	public static final int INTERVAL = 1000;
	
	private File file;
	
	public ProcLock(File file) {
		this.file = file;
	}
	
	/**
	 * because in unix/linux, file can be delete when other read
	 * @return 0 when success
	 *         -1 when fail
	 */
	public int lock() {
		try {
			if (file != null && !file.exists() && file.createNewFile()) {
				new Thread() {
					public void run() {
						InputStream in = null;
						try {
							in = new FileInputStream(file);
							while (in.read() < 0) {
								Util.msleep(INTERVAL);
							}
							setChanged();
							notifyObservers();
						} catch (IOException e) {
						} finally {
							try {
								in.close();
							} catch (IOException e) {
							}
							if (file.exists()) {
								file.delete();
							}
						}
					}
				}.start();
				return 0; // success to lock
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public int free() {
		if(file != null && file.exists()) {
			OutputStream out = null;
			try {
				out = new FileOutputStream(file);
				out.write(0x00);
				return 0; // success to free lock
			} catch (IOException e) {
			} finally {
				try {
					out.close();
				} catch (IOException e) {
				}
				if (file.exists()) {
					file.delete();
				}
			}
		}
		return -1;
	}
}
